{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "* By: Illya Barziy\n",
    "* Email: illyabarziy@gmail.com\n",
    "* Reference: Advances in Financial Machine Learning, Chapter-15"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Chapter 15 Understanding Strategy Risk"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Introduction"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "As the majority of the investment strategies have exit conditions (either in a form of stop loss or take profit), the outcomes can be modeled using a binomial process. This approach shows whether the strategy is sensitive to minor changes in betting frequency, odds, and payouts. \n",
    "\n",
    "In this notebook, the exercises from Chapter-15 in the book \"Advances in Financial Machine Learning\" are implemented. "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {},
   "outputs": [],
   "source": [
    "import numpy as np\n",
    "import pandas as pd\n",
    "import scipy.stats as ss\n",
    "from random import gauss\n",
    "from itertools import product\n",
    "import matplotlib.pyplot as plt\n",
    "import mlfinlab as ml"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Question-15.1"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### A portfolio manager intends to launch a strategy that targets an annualized SR of 2. Bets have a precision rate of 60%, with weekly frequency. The exit conditions are 2% for profit-taking, and –2% for stop-loss.\n",
    "\n",
    "### (a) Is this strategy viable?"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Sharpe Ratio is 1.472434737843829\n"
     ]
    }
   ],
   "source": [
    "'''\n",
    "We assume the exit conditions to be for log returns, therefore we can assume payouts being symmetric.\n",
    "\n",
    "Using the Snippet 15.1:\n",
    "'''\n",
    "trades_per_year = 52\n",
    "out,p=[],.6\n",
    "\n",
    "for i in range(1000000):\n",
    "    rnd=np.random.binomial(n=1,p=p)\n",
    "    x=(1 if rnd==1 else -1)\n",
    "    out.append(x)\n",
    "\n",
    "#Using mlfinlab function that takes pd.Series as an input\n",
    "out = pd.Series(out)\n",
    "annualized_sr = ml.backtest_statistics.sharpe_ratio(out, entries_per_year=trades_per_year)\n",
    "\n",
    "print('Sharpe Ratio is' , annualized_sr)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Wigh given parameters, the Sharpe Ratio of the strategy falls below the desired threshold of 2, therefore the strategy is __not__ viable."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### (b) _Ceteris paribus_, what is the required precision rate that would make the strategy profitable?"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Required precision is 0.6336306209562121\n"
     ]
    }
   ],
   "source": [
    "'''\n",
    "Using the formula solution:\n",
    "'''\n",
    "n, SR = 52, 2\n",
    "\n",
    "precision = 1/2 * (1 + (1-n/(SR**2+n))**(1/2))\n",
    "\n",
    "print('Required precision is' , precision)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "So, an increase of precision from 0.6 set by the manager to 0.63363 will make the strategy profitable at a required Sharpe Ratio of 2."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### (c) For what betting frequency is the target achievable?"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Using formula solutions:\n",
    "\n",
    "$\\frac{n}{\\theta^2+n}=-4p^2+4p$\n",
    "\n",
    "$n=(-4p^2+4p)*(\\theta^2+n)$\n",
    "\n",
    "$n - n(-4p^2+4p)=(-4p^2+4p)*\\theta^2$\n",
    "\n",
    "$n=\\frac{(-4p^2+4p)*\\theta^2}{1+4p^2-4p}$"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Required frequeny is 95.99999999999991\n"
     ]
    }
   ],
   "source": [
    "p, SR = 0.6, 2\n",
    "\n",
    "n = ((-4*p**2 +4*p) * SR**2) / (1 + 4*p**2 - 4*p)\n",
    "\n",
    "print('Required frequeny is' , n)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "96 trades per year should be made instead of 52 (or ~85% more trades) to achieve the target Sharpe Ratio."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### (d) For what profit-taking threshold is the target achievable?"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Changing the profit-taking threshold will bring us to the asymmetric payouts model, where the solution is:\n",
    "\n",
    "$\\theta=\\frac{(\\pi_{+}-\\pi_{-})p+\\pi_{-}}{(\\pi_{+}-\\pi_{-})\\sqrt{p(1-p)}}\\sqrt{n}$\n",
    "\n",
    "$(\\pi_{+}-\\pi_{-})(\\theta*\\sqrt{p(1-p)})=((\\pi_{+}-\\pi_{-})p+\\pi_{-})\\sqrt{n}$\n",
    "\n",
    "$(\\pi_{+}-\\pi_{-})(\\theta*\\sqrt{p(1-p)}-p\\sqrt{n})=\\pi_{-}\\sqrt{n}$\n",
    "\n",
    "$\\pi_{+}-\\pi_{-}=\\frac{\\pi_{-}\\sqrt{n}}{(\\theta*\\sqrt{p(1-p)}-p\\sqrt{n})}$\n",
    "\n",
    "$\\pi_{+}=\\frac{\\pi_{-}\\sqrt{n}}{(\\theta*\\sqrt{p(1-p)}-p\\sqrt{n})}+\\pi_{-}$"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Required take-profit is 0.023091676456151216\n"
     ]
    }
   ],
   "source": [
    "p, SR, sl, n = 0.6, 2, -0.02, 52\n",
    "\n",
    "tp = (sl * n**(1/2)) / (SR * (p*(1-p))**(1/2) - p * n**(1/2)) + sl\n",
    "\n",
    "print('Required take-profit is' , tp)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Achieving the target is possible if the take-profit is moved from 0.02 to ~0.023 (or 15,5% higher)."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### (e) What would be an alternative stop-loss?"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Again, using the asymmetric payouts model solution:\n",
    "\n",
    "$\\theta=\\frac{(\\pi_{+}-\\pi_{-})p+\\pi_{-}}{(\\pi_{+}-\\pi_{-})\\sqrt{p(1-p)}}\\sqrt{n}$\n",
    "\n",
    "$(\\pi_{+}-\\pi_{-})(\\theta*\\sqrt{p(1-p)})=((\\pi_{+}-\\pi_{-})p+\\pi_{-})\\sqrt{n}$\n",
    "\n",
    "$(\\pi_{+}-\\pi_{-})(\\theta*\\sqrt{p(1-p)}-p\\sqrt{n})=\\pi_{-}\\sqrt{n}$\n",
    "\n",
    "$\\pi_{-}(\\theta*\\sqrt{p(1-p)}-p\\sqrt{n})+\\pi_{-}\\sqrt{n} = \\pi_{+}(\\theta*\\sqrt{p(1-p)}-p\\sqrt{n})$\n",
    "\n",
    "$\\pi_{-}(\\theta*\\sqrt{p(1-p)}-p\\sqrt{n}+ \\sqrt{n}) = \\pi_{+}(\\theta*\\sqrt{p(1-p)}-p\\sqrt{n})$\n",
    "\n",
    "$\\pi_{-} = \\frac{\\pi_{+}(\\theta*\\sqrt{p(1-p)}-p\\sqrt{n})}{\\theta*\\sqrt{p(1-p)}-p\\sqrt{n}+ \\sqrt{n}}$"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Required stop-loss is -0.017322258986243812\n"
     ]
    }
   ],
   "source": [
    "p, SR, tp, n = 0.6, 2, 0.02, 52\n",
    "\n",
    "sl = (tp * (SR * (p*(1-p))**(1/2) - p * n**(1/2))) / (SR * (p*(1-p))**(1/2) - p * n**(1/2) + n**(1/2))\n",
    "\n",
    "print('Required stop-loss is' , sl)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "An alternative stop-loss would be ~-0.0173 instead of -0.02 (or 13,4% lower)."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Question-15.2"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Following up on the strategy from exercise 1.\n",
    "\n",
    "### (a) What is the sensitivity of SR to a 1% change in each parameter?"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Change of 1% in percision rate shifts SR from 1.4719601443879742 to 1.5643110535917948 or 6.274008814431532 %\n",
      "Change of 1% in trading frequency shifts SR from 1.4719601443879742 to 1.4793016370346288 or 0.4987562112089074 %\n",
      "Change of 1% in stop-loss shifts SR from 1.4719601443879746 to 1.435344220398224 or -2.487562189054722 %\n",
      "Change of 1% in take-profit shifts SR from 1.4719601443879746 to 1.5085760683777247 or 2.487562189054692 %\n"
     ]
    }
   ],
   "source": [
    "'''\n",
    "For the original parameters:\n",
    "'''\n",
    "p, n = 0.6, 52\n",
    "\n",
    "SR_sym = lambda p, n: (2*p - 1) / (2 * (p*(1-p))**(1/2)) * (n)**(1/2)\n",
    "\n",
    "#precision rate\n",
    "print('Change of 1% in percision rate shifts SR from' , SR_sym(p, n), 'to',\n",
    "      SR_sym(p * 1.01, n), 'or', (SR_sym(p * 1.01, n)-SR_sym(p, n))/SR_sym(p, n)*100, '%')\n",
    "\n",
    "#trading frequency\n",
    "print('Change of 1% in trading frequency shifts SR from' , SR_sym(p, n), 'to',\n",
    "      SR_sym(p, n * 1.01), 'or', (SR_sym(p, n* 1.01)-SR_sym(p, n))/SR_sym(p, n)*100, '%')\n",
    "\n",
    "sl, tp = -0.02, 0.02\n",
    "\n",
    "SR_asym = lambda p, n, sl, tp: ((tp - sl) * p + sl) / ((tp - sl) * (p*(1-p))**(1/2)) * n**(1/2)\n",
    "\n",
    "#stop-loss\n",
    "print('Change of 1% in stop-loss shifts SR from' , SR_asym(p, n, sl, tp), 'to',\n",
    "      SR_asym(p, n , sl * 1.01, tp), 'or', (SR_asym(p, n, sl * 1.01, tp)-SR_asym(p, n, sl, tp))/SR_asym(p, n, sl, tp)*100, '%')\n",
    "\n",
    "#take-profit\n",
    "print('Change of 1% in take-profit shifts SR from' , SR_asym(p, n, sl, tp), 'to',\n",
    "      SR_asym(p, n , sl , tp * 1.01), 'or', (SR_asym(p, n, sl, tp * 1.01)-SR_asym(p, n, sl, tp))/SR_asym(p, n, sl, tp)*100, '%')"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "The Sharpe Ratio of the original model is most sensitive towards changes in precision rate. The trading frequency 1% change affects SR 12 times less than the precision rate change. Changes of SR from changes in stop-loss or take-profit values are symmetric."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### (b) Given these sensitivities, and assuming that all parameters are equally hard to improve, which one offers the lowest hanging fruit?"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "In this situation improving the precision rate would have the best effect on Sharpe Ratio, next goes both stop-loss decrease and take-profit increase. Trading frequency would have the least effect on SR."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### (c) Does changing any of the parameters in exercise 1 impact the others? For example, does changing the betting frequency modify the precision rate, etc.?"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "In the model, we assumed that changes in the input values - precision rate, frequency rate, stop-loss, and take-profit only affect the Sharpe Ratio. However, in real life examples increase in the betting frequency may decrease the precision rate, as trading opportunities that are less certain are taken."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Question-15.3"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Suppose a strategy that generates monthly bets over two years, with returns following a mixture of two Gaussian distributions. The first distribution has a mean of –0.1 and a standard deviation of 0.12. The second distribution has a mean of 0.06 and a standard deviation of 0.03. The probability that a draw comes from the first distribution is 0.15.\n",
    "\n",
    "### (a) Following Lopez de Prado and Peijan [2004] and Lopez de Prado and Foreman [2014], derive the first four moments for the mixture’s returns."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "From _\"A mixture of Gaussians approach to mathematical portfolio oversight: the EF3M algorithm\"_ - Lopez de Prado and Foreman [2014], Appendix 1:\n",
    "\n",
    "$E[r] = \\sum_{j=1}^m p_j\\mu_j$\n",
    "\n",
    "$E[r^2] = \\sum_{j=1}^m p_j (\\sigma_j^2 + \\mu_j^2)$\n",
    "\n",
    "$E[r^3] = \\sum_{j=1}^m p_j (3\\sigma_j^2\\mu_j + \\mu_j^3)$\n",
    "\n",
    "$E[r^4] = \\sum_{j=1}^m p_j (3\\sigma_j^4 + 6\\sigma_j^2\\mu_j^2 + \\mu_j^4)$"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "First moment for the returns: 0.036\n",
      "Second moment for the returns: 0.0074849999999999995\n",
      "Third moment for the returns: -0.00047670000000000004\n",
      "Fourth moment for the returns: 0.0002675175\n"
     ]
    }
   ],
   "source": [
    "μ1, μ2, σ1, σ2, p = -0.1, 0.06, 0.12, 0.03, 0.15\n",
    "\n",
    "E_r1 = p*μ1 + (1-p)*μ2\n",
    "print('First moment for the returns:', E_r1)\n",
    "\n",
    "E_r2 = p*(σ1**2 + μ1**2) + (1-p)*(σ2**2 + μ2**2)\n",
    "print('Second moment for the returns:', E_r2)\n",
    "\n",
    "E_r3 = p*(3 * σ1**2 * μ1 + μ1**3) + (1-p)*(3 * σ2**2 * μ2 + μ2**3)\n",
    "print('Third moment for the returns:', E_r3)\n",
    "\n",
    "E_r4 = p*(3 * σ1**4 + 6 * σ1**2 * μ1**2 + μ1**4) + (1-p)*(3 * σ2**4 + 6 * σ2**2 * μ2**2 + μ2**4)\n",
    "print('Fourth moment for the returns:', E_r4)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### (b) What is the annualized SR?"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Sharpe Ratio from moments:\n",
    "\n",
    "$V[r] = E[r^2] - E[r]^2$\n",
    "\n",
    "$\\theta = \\frac{nE[r]}{\\sqrt{nV[r]}}$\n",
    "\n",
    "$\\theta = \\frac{\\sqrt{n}E[r]}{\\sqrt{E[r^2] - E[r]^2}}$"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Annualized Sharpe Ratio: 1.5851956884937564\n"
     ]
    }
   ],
   "source": [
    "n, years = 12, 2\n",
    "\n",
    "SR = (n**(1/2) * E_r1) / (E_r2 - E_r1**2)**(1/2)\n",
    "print('Annualized Sharpe Ratio:', SR)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### (c) Using those moments, compute PSR[1] (see Chapter 14). At a 95% confidence level, would you discard this strategy?"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "From Chapter 14:\n",
    "\n",
    "$PSR[SR^*] = z[\\frac{(SR - SR^*)\\sqrt{T-1}}{\\sqrt{1-\\gamma_3SR + \\frac{\\gamma_4-1}{4}SR^2}}]$"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Probabilistic Sharpe Ratio: 0.969142321714641\n"
     ]
    }
   ],
   "source": [
    "'''\n",
    "As our strategy returns are a combination of two Gaussian, they are Gaussian, so skewness = 0, kurtosis = 3.\n",
    "'''\n",
    "γ3, γ4, T, SR_ = 0, 3, years * n, 1\n",
    "\n",
    "#Using mlfinlab finction\n",
    "probabilistic_sr = ml.backtest_statistics.probabilistic_sharpe_ratio(observed_sr=SR, \n",
    "                                                                     benchmark_sr=SR_, \n",
    "                                                                     number_of_returns=T, \n",
    "                                                                     skewness_of_returns=γ3, \n",
    "                                                                     kurtosis_of_returns=γ4)\n",
    "\n",
    "print('Probabilistic Sharpe Ratio:', probabilistic_sr)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "According to the PSR statistic description in Chapter 14, it should exceed 0.95 for the 5% significance level. Our calculated PSR is above that threshold, therefore we __do not discard__ the strategy."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Question-15.4"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Using Snippet 15.5, compute $P[p < p_{\\theta^*=1}]$ for the strategy described in exercise 3. At a significance level of 0.05, would you discard this strategy? Is this result consistent with PSR[$\\theta^*$]?"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "metadata": {},
   "outputs": [],
   "source": [
    "'''\n",
    "Snippet 15.5 with needed parameters:\n",
    "'''\n",
    "def binHR(sl,pt,freq,tSR):\n",
    "    '''\n",
    "    Given a trading rule characterized by the parameters {sl,pt,freq},\n",
    "    what's the min precision p required to achieve a Sharpe ratio tSR?\n",
    "    1) Inputs\n",
    "    sl: stop loss threshold\n",
    "    pt: profit taking threshold\n",
    "    freq: number of bets per year\n",
    "    tSR: target annual Sharpe ratio\n",
    "    2) Output\n",
    "    p: the min precision rate p required to achieve tSR\n",
    "    '''\n",
    "    a=(freq+tSR**2)*(pt-sl)**2\n",
    "    b=(2*freq*sl-tSR**2*(pt-sl))*(pt-sl)\n",
    "    c=freq*sl**2\n",
    "    p=(-b+(b**2-4*a*c)**0.5)/(2*a)\n",
    "    return p\n",
    "#———————————————————————————————————————\n",
    "def mixGaussians(mu1,mu2,sigma1,sigma2,prob1,nObs):\n",
    "    # Random draws from a mixture of gaussians\n",
    "    ret1=np.random.normal(mu1,sigma1,size=int(nObs*prob1))\n",
    "    ret2=np.random.normal(mu2,sigma2,size=int(nObs)-ret1.shape[0])\n",
    "    ret=np.append(ret1,ret2,axis=0)\n",
    "    np.random.shuffle(ret)\n",
    "    return ret\n",
    "#———————————————————————————————————————\n",
    "def probFailure(ret,freq,tSR):\n",
    "    # Derive probability that strategy may fail\n",
    "    rPos,rNeg=ret[ret>0].mean(),ret[ret<=0].mean()\n",
    "    p=ret[ret>0].shape[0]/float(ret.shape[0])\n",
    "    thresP=binHR(rNeg,rPos,freq,tSR)\n",
    "    risk=ss.norm.cdf(thresP,p,p*(1-p)) # approximation to bootstrap\n",
    "    return risk\n",
    "#———————————————————————————————————————\n",
    "def main():\n",
    "    #1) Parameters\n",
    "    mu1,mu2,sigma1,sigma2,prob1,nObs=-0.1, 0.06, 0.12, 0.03, 0.15, 24\n",
    "    tSR,freq=1 ,12\n",
    "    #2) Generate sample from mixture\n",
    "    ret=mixGaussians(mu1,mu2,sigma1,sigma2,prob1,nObs)\n",
    "    #3) Compute prob failure\n",
    "    probF=probFailure(ret,freq,tSR)\n",
    "    print('Prob strategy will fail',probF)\n",
    "    return"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 13,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Prob strategy will fail 0.024407769974328797\n"
     ]
    }
   ],
   "source": [
    "main()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "The probability of strategy to fail is higher than the 0.05 threshold, so we should discard the strategy. The result is not consistent with the PSR. One of the reasons for that may be a small number of observations to approximate the probability."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Question-15.5"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### In general, what result do you expect to be more accurate, PSR[𝜃∗] or P[p < p𝜃∗=1]? How are these two methods complementary?"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "The result from the second algorithm is expected to be more accurate, as it's solely based and includes all the variables that are under the control of a portfolio manager. "
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Question-15.6"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Re-examine the results from Chapter 13, in light of what you have learned in this chapter.\n",
    "\n",
    "### (a) Does the asymmetry between profit taking and stop-loss thresholds in OTRs make sense?"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "From examples in Chapter 13, the SR is maximized when there is an asymmetry - take profits are low and stop losses are high. From our sensitivity analysis, both decrease take-profits and increase in stop-losses will result in decreased Sharpe Ratio."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### (b) What is the range of p implied by Figure 13.1, for a daily betting frequency?"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 14,
   "metadata": {},
   "outputs": [],
   "source": [
    "'''\n",
    "From Chapter 13 on OTRs determination:\n",
    "'''\n",
    "\n",
    "def batch(coeffs,nIter=1e5,maxHP=100,rPT=np.linspace(.5,10,20), rSLm=np.linspace(.5,10,20),seed=0):\n",
    "    phi,output1=2**(-1./coeffs['hl']),[] \n",
    "    n = 0\n",
    "    for comb_ in product(rPT,rSLm):\n",
    "        n = n + 1\n",
    "        if n % 20 == 0:\n",
    "            print(n)\n",
    "        output2=[]\n",
    "        for iter_ in range(int(nIter)):\n",
    "            p,hp,count=seed,0,0\n",
    "            while True:\n",
    "                p=(1-phi)*coeffs['forecast']+phi*p+coeffs['sigma']*gauss(0,1)\n",
    "                cP=p-seed;hp+=1\n",
    "                if cP>comb_[0] or cP<-comb_[1] or hp>maxHP:\n",
    "                    output2.append(cP)\n",
    "                    break\n",
    "        mean,std=np.mean(output2),np.std(output2)\n",
    "        #print(comb_[0],comb_[1],mean,std,mean/std)\n",
    "        output1.append((comb_[0],comb_[1],mean,std,mean/std))\n",
    "    return output1"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 15,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "20\n",
      "40\n",
      "60\n",
      "80\n",
      "100\n",
      "120\n",
      "140\n",
      "160\n",
      "180\n",
      "200\n",
      "220\n",
      "240\n",
      "260\n",
      "280\n",
      "300\n",
      "320\n",
      "340\n",
      "360\n",
      "380\n",
      "400\n",
      "420\n",
      "440\n"
     ]
    }
   ],
   "source": [
    "rPT=rSLm=np.linspace(0,10,21)\n",
    "coeffs={'forecast':0,'hl':5,'sigma':1}\n",
    "output=batch(coeffs,nIter=1e5,maxHP=100,rPT=rPT,rSLm=rSLm)\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "From the data used to generate Figure 13.1 (using Snippets in Chapter 13), we can calculate p for each situation using solution from Chapter 15. As we have asymmetric payoffs:\n",
    "\n",
    "$a = (n+\\theta^2)(\\pi_{+}-\\pi_{-})^2$\n",
    "\n",
    "$b = [2n\\pi_{-}-\\theta^2(\\pi_{+}-\\pi_{-})](\\pi_{+}-\\pi_{-})$\n",
    "\n",
    "$c = n\\pi_{-}^2$\n",
    "\n",
    "$p = \\frac{-b+\\sqrt{b^2-4ac}}{2a}$"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 16,
   "metadata": {},
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "D:\\programs\\Anaconda\\envs\\myenv1\\lib\\site-packages\\ipykernel_launcher.py:13: RuntimeWarning: invalid value encountered in double_scalars\n",
      "  del sys.path[0]\n"
     ]
    }
   ],
   "source": [
    "n = 252 # assume daily trading\n",
    "\n",
    "p_values = []\n",
    "p_boundary = []\n",
    "for el in output:\n",
    "    tp, sl, _, _, SR = el\n",
    "    sl = -sl\n",
    "    \n",
    "    a = (n + SR**2) * (tp - sl)**2\n",
    "    b = (2 * n * sl - SR**2 * (tp - sl)) * (tp - sl)\n",
    "    c = n * sl**2\n",
    "    \n",
    "    p = (-b + (b**2 - 4 * a * c)**(1/2)) / (2 * a)\n",
    "    if tp == 0 or sl == 0:\n",
    "        p_boundary.append(p)    \n",
    "        continue\n",
    "    p_values.append(p)\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 17,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "For the cases where both SL and TP are above 0:\n",
      "Minimum value is: 0.08585896559591545\n",
      "Maximum value is: 0.9741854973202934\n"
     ]
    },
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<Figure size 432x288 with 1 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "print('For the cases where both SL and TP are above 0:')\n",
    "\n",
    "print('Minimum value is:', min(p_values))\n",
    "print('Maximum value is:', max(p_values))\n",
    "\n",
    "_ = plt.hist(p_values, bins=60)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 18,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "In other cases:\n",
      "When SL is 0, the p is close to 0. So the minimum value is: 2.776358742776316e-07\n",
      "When TP is 0, the p is close to 1. So the maximum value is: 1.000000000383423\n"
     ]
    },
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<Figure size 432x288 with 1 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "print('In other cases:')\n",
    "p_boundary = [x for x in p_boundary if str(x) != 'nan']\n",
    "\n",
    "print('When SL is 0, the p is close to 0. So the minimum value is:', min(p_boundary))\n",
    "print('When TP is 0, the p is close to 1. So the maximum value is:', max(p_boundary))\n",
    "\n",
    "_ = plt.hist(p_boundary, bins=60)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "So, the range of p implied by Figure 13.1 goes from 0.085 to 0.974"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### (c) What is the range of p implied by Figure 13.5, for a weekly betting frequency?"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 19,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "20\n",
      "40\n",
      "60\n",
      "80\n",
      "100\n",
      "120\n",
      "140\n",
      "160\n",
      "180\n",
      "200\n",
      "220\n",
      "240\n",
      "260\n",
      "280\n",
      "300\n",
      "320\n",
      "340\n",
      "360\n",
      "380\n",
      "400\n",
      "420\n",
      "440\n"
     ]
    }
   ],
   "source": [
    "rPT=rSLm=np.linspace(0,10,21)\n",
    "coeffs={'forecast':0,'hl':100,'sigma':1}\n",
    "output=batch(coeffs,nIter=1e5,maxHP=100,rPT=rPT,rSLm=rSLm)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 20,
   "metadata": {},
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "D:\\programs\\Anaconda\\envs\\myenv1\\lib\\site-packages\\ipykernel_launcher.py:13: RuntimeWarning: invalid value encountered in double_scalars\n",
      "  del sys.path[0]\n"
     ]
    }
   ],
   "source": [
    "n = 52 # assume weekly trading\n",
    "\n",
    "p_values = []\n",
    "p_boundary = []\n",
    "for el in output:\n",
    "    tp, sl, _, _, SR = el\n",
    "    sl = -sl\n",
    "    \n",
    "    a = (n + SR**2) * (tp - sl)**2\n",
    "    b = (2 * n * sl - SR**2 * (tp - sl)) * (tp - sl)\n",
    "    c = n * sl**2\n",
    "    \n",
    "    p = (-b + (b**2 - 4 * a * c)**(1/2)) / (2 * a)\n",
    "    if tp == 0 or sl == 0:\n",
    "        p_boundary.append(p)    \n",
    "        continue\n",
    "    p_values.append(p)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 21,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "For the cases where both SL and TP are above 0:\n",
      "Minimum value is: 0.04980489467000023\n",
      "Maximum value is: 0.9545803863979788\n"
     ]
    },
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<Figure size 432x288 with 1 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "print('For the cases where both SL and TP are above 0:')\n",
    "\n",
    "print('Minimum value is:', min(p_values))\n",
    "print('Maximum value is:', max(p_values))\n",
    "\n",
    "_ = plt.hist(p_values, bins=60)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 22,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "In other cases:\n",
      "When SL is 0, the p is close to 0. So the minimum value is: 1.1188340856647339e-08\n",
      "When TP is 0, the p is close to 1. So the maximum value is: 1.0000000002395149\n"
     ]
    },
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<Figure size 432x288 with 1 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "print('In other cases:')\n",
    "p_boundary = [x for x in p_boundary if str(x) != 'nan']\n",
    "\n",
    "print('When SL is 0, the p is close to 0. So the minimum value is:', min(p_boundary))\n",
    "print('When TP is 0, the p is close to 1. So the maximum value is:', max(p_boundary))\n",
    "\n",
    "_ = plt.hist(p_boundary, bins=60)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "With an increased half-life from 5 to 100 we can see that the p distribution is much more narrow."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Conclusion"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "The chapter provides formula solutions, showing dependencies between:\n",
    " * SR (or $\\theta$) - Sharpe Ratio of the strategy;\n",
    " * n - trading frequency in trades per year;\n",
    " * p - precision rate of a trade;\n",
    " * $\\pi_{-}$ and $\\pi_{+}$ - Stop-Loss and Take-Profit Levels of a strategy;\n",
    "\n",
    "As well as an algorithm for calculating the probability of strategy failure for a mixture of two Gaussian distributions. Required inputs are:\n",
    " * $\\mu_{1}$, $\\mu_{2}$, $\\sigma_{1}$, $\\sigma_{1}$ - mean and variance parameters of the distributions;\n",
    " * p - robability of picking one of them;\n",
    " * t - number of observations (total trades);\n",
    " * n - trading frequency (trades in a year);\n",
    " * tSR - target Sharpe Ratio;\n",
    "\n",
    "Key takeways from the chapter:\n",
    "\n",
    " * From the first set of variables above, the Sharpe Ratio is most sensitive to changes in precision rate. Next, come the stop-loss or take-profit changes (and are symmetric), lastly goes trading frequency. \n",
    " \n",
    " * PSR and Strategy Failure Algorithm can both be used to check if strategy fits the Sharpe Ratio requirements, however, the later is more accurate and takes into account only parameters that are under the control of the portfolio manager. \n",
    " \n",
    " * From Examples in Chapter 13, if Stop-Loss levels are close to 0, the precision rate is close to 0; if Take-Profit is close to 0, the precision rate is close to 1.  \n",
    "\n",
    "Papers used in the chapter:\n",
    "\n",
    "* Lopez de Prado, M. and M. Foreman (2014): “A mixture of Gaussians approach to mathematical portfolio oversight: The EF3M algorithm.” Quantitative Finance, Vol. 14, No. 5, pp. 913–930. Available at https://ssrn.com/abstract=1931734. (Includes moments computation formulas. The EF3M algorithm itself aims to determine parameters of the two Gaussian distributions in a mixture.)"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "myenv1",
   "language": "python",
   "name": "myenv1"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.7.6"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 4
}
